package com.carbon.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.carbon.common.core.domain.AjaxResult;
import com.carbon.common.core.text.Convert;
import com.carbon.common.utils.SecurityUtils;
import com.carbon.common.utils.poi.ExcelUtil;
import com.carbon.common.utils.uuid.IdUtils;
import com.carbon.domain.*;
import com.carbon.dto.GoodDto;
import com.carbon.dto.StorageDto;
import com.carbon.dto.WareDto;
import com.carbon.dto.WareInDto;
import com.carbon.service.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import com.carbon.utils.OrderIdUtil;
import com.carbon.vo.SearchParams;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

/**
 * 入库信息(Storage)表控制层
 *
 * @author WangFK
 * @since 2023-08-21 13:19:46
 */
@RestController
@Slf4j
@RequestMapping("/wms/grain")
public class StorageController {
    /**
     * 服务对象
     */
    @Resource
    private StorageService storageService;
    @Resource
    private WareService wareService;
    @Resource
    private StorageGoodsService storageGoodsService;
    @Resource
    private GoodsService goodsService;
    @Resource
    private BatchService batchService;
    @Resource
    private ProviderService providerService;

    /**
     * 入库详情显示
     *
     * @param params
     * @return
     */
    @GetMapping("/listIn")
    public AjaxResult listIn(SearchParams params) {
        Page<Storage> page = new Page<>(params.getPageNum(), params.getPageSize());
        LambdaUpdateWrapper<Storage> lqw = new LambdaUpdateWrapper<Storage>()
                .eq(Storage::getRepairStatus, "1")
                .eq(Storage::getEnterStatus, "1")
                .eq(ObjectUtil.isNotEmpty(params.getBusinessId()), Storage::getBusinessId, params.getBusinessId())
                .eq(ObjectUtil.isNotEmpty(params.getContractId()), Storage::getContractId, params.getContractId())
                .eq(ObjectUtil.isNotEmpty(params.getProviderId()), Storage::getProviderId, params.getProviderId());

        List<String> productNameList = params.getProductNameList();
        List<String> wareList = params.getWareList();
        if (ObjectUtil.isNotEmpty(productNameList)) {
            lqw.eq(Storage::getBatchId, productNameList.get(productNameList.size() - 1));
        }
        if (ObjectUtil.isNotEmpty(wareList)) {
            lqw.eq(Storage::getWareId, wareList.get(wareList.size() - 1));
        }
        String dateTime = params.getDateTime();
        if (ObjectUtil.isNotEmpty(dateTime)) {
            lqw.like(Storage::getCreateTime, dateTime).or()
                    .like(Storage::getUpdateTime, dateTime);
        }
        page = storageService.page(page, lqw);
        List<Storage> records = page.getRecords();
        if (records.isEmpty()) {
            return AjaxResult.success();
        }
        List<Long> collect = records.stream().map(Storage::getId).distinct().collect(Collectors.toList());

        ArrayList<WareInDto> goodListByStorageIdList = new ArrayList<>();
        for (Long aLong : collect) {
            WareInDto goodListByStorageIdInfo = storageService.getGoodListByStorageIdInfo(aLong);
            if (ObjectUtil.isNotEmpty(goodListByStorageIdInfo)){
                goodListByStorageIdList.add(goodListByStorageIdInfo);
            }
        }
        goodListByStorageIdList.stream().forEach(item -> {
            WareDto wareNodeById = wareService.getWareNodeById(Convert.toInt(item.getWareId()));
            if (ObjectUtil.isNotEmpty(wareNodeById)) {
                item.setWareAreaDto(wareNodeById.getWareAreaDto());
                item.setWarePositionDto(wareNodeById.getWarePositionDto());
                item.setWareNameDto(wareNodeById.getWareNameDto());
            }
            Batch productByBatchId = batchService.getProductByBatchId(Convert.toInt(item.getBatchId()));
            if (ObjectUtil.isNotEmpty(productByBatchId)) {
                item.setBatchName(productByBatchId.getBatchId());
                item.setProductInfoName(productByBatchId.getProductName());
            }
            Provider byId = providerService.getById(item.getProviderId());
            if (byId != null) {
                item.setProviderName(byId.getName());
            }
        });
        return AjaxResult.success()
                .put("rows", goodListByStorageIdList)
                .put("total", page.getTotal());
    }

    /**
     * 根据分页条件导出
     *
     * @param response
     * @param params
     */
    @PostMapping("/export")
    public void export(HttpServletResponse response, SearchParams params) {
        AjaxResult result = listIn(params);
        List<WareInDto> rows = JSONUtil.toList(JSONUtil.toJsonStr(result.get("rows")), WareInDto.class);
        ExcelUtil<WareInDto> util = new ExcelUtil<WareInDto>(WareInDto.class);
        util.exportExcel(response, rows, "入库报表");
    }

    /**
     * 获取所有信息
     *
     * @return
     */
    @GetMapping("/getInfoList")
    public AjaxResult getInfoList() {
        List<Storage> list = storageService.list();
        return AjaxResult.success(list);
    }

    /**
     * 获取所有单据号
     *
     * @return
     */
    @GetMapping("/getOrderIdList")
    public AjaxResult getOrderIdList() {
        LambdaUpdateWrapper<Storage> lqw = new LambdaUpdateWrapper<Storage>()
                .eq(Storage::getRepairStatus, "1")
                .eq(Storage::getEnterStatus, "0")
                .eq(Storage::getStorageStatus, '0');
        List<Storage> list = storageService.list(lqw);
        return AjaxResult.success(list);
    }

    /**
     * 添加库存商品关联表信息
     *
     * @param storageDto
     * @return
     */
    @PostMapping("/addStorageInfoGoods")
    public AjaxResult addStorageInfoGoods(@RequestBody StorageDto storageDto) {
        return AjaxResult.success();
    }

    /**
     * 删除库存商品关联表信息
     *
     * @param storageId
     * @param goodsId
     * @return
     */
    @DeleteMapping("/delStorageInfoGoods")
    public AjaxResult delStorageInfoGoods(Long storageId, String goodsId) {
        List<String> split = StrUtil.split(goodsId, ",").stream().filter(item -> {
            if (ObjectUtil.isEmpty(item)) {
                return false;
            }
            return true;
        }).distinct().collect(Collectors.toList());
        LambdaUpdateWrapper<StorageGoods> lqw = new LambdaUpdateWrapper<StorageGoods>()
                .eq(StorageGoods::getStorageId, storageId)
                .in(StorageGoods::getGoodsId, split);
        return storageGoodsService.remove(lqw) ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 修改入库审核状态
     *
     * @param id
     * @param enterStatus
     * @return
     */
    @PutMapping("/updateEnterStatus")
    public AjaxResult updateEnterStatus(Long id, String enterStatus) {
        Storage storage = new Storage();
        storage.setId(id);
        storage.setEnterStatus(enterStatus);
        storage.setCreateStatus("1");
        // 审核通过
        if ("1".equalsIgnoreCase(enterStatus)) {
            // 审核通过 入库单号
            storage.setWareinId(OrderIdUtil.getOrderId());
            storage.setUpdateStatus("1");
        } else {
            storage.setUpdateStatus("0");
        }

        return storageService.updateById(storage) ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 修改补货审核状态
     *
     * @param id
     * @param repairStatus
     * @return
     */
    @PutMapping("/updateRepairStatus")
    public AjaxResult updateRepairStatus(Long id, String repairStatus) {
        Storage storage = new Storage();
        storage.setId(id);
        storage.setRepairStatus(repairStatus);
        // 审核通过
        if ("1".equalsIgnoreCase(repairStatus)) {
            storage.setUpdateStatus("1");
            storage.setCreateStatus("0");
        } else {
            storage.setUpdateStatus("0");
            storage.setCreateStatus("1");
        }

        return storageService.updateById(storage) ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 修改审核状态
     *
     * @param id
     * @param createStatus
     * @return
     */
    @GetMapping("/changeCreateStatus")
    public AjaxResult changeCreateStatus(Long id, String createStatus) {
        Storage storage = new Storage();
        storage.setId(id);
        // 未提交
        storage.setCreateStatus(createStatus);
        return storageService.updateById(storage) ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 入库
     *
     * @param id
     * @return
     */
    @GetMapping("/changeGrainStatus")
    public AjaxResult changeGrainStatus(Long id) {
        Storage byId = storageService.getById(id);
        if (!"1".equalsIgnoreCase(byId.getUpdateStatus())) {
            return AjaxResult.error("请按规范操作");
        }
        Storage storage = new Storage();
        storage.setId(id);
        storage.setStorageStatus("1");
        storage.setWareinId(OrderIdUtil.getOrderId());
        LambdaUpdateWrapper<StorageGoods> lqw = new LambdaUpdateWrapper<StorageGoods>()
                .eq(StorageGoods::getStorageId, id);
        List<StorageGoods> list = storageGoodsService.list(lqw);
        list.stream().forEach(item -> {
            Goods byId1 = goodsService.getById(item.getGoodsId());
            if (byId1 != null) {
                byId1.setGoodsTotal(byId1.getGoodsTotal() + item.getReplenishmentNum());
                byId1.setGoodsNum(byId1.getGoodsNum() + item.getReplenishmentNum());
                goodsService.updateById(byId1);
            }
        });
        return storageService.updateById(storage) ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 分页查询
     *
     * @param params
     * @return
     */
    @GetMapping("/list")
    public AjaxResult list(SearchParams params) {
        Page<Storage> page = new Page<>(params.getPageNum(), params.getPageSize());
        LambdaUpdateWrapper<Storage> lqw = new LambdaUpdateWrapper<Storage>()
                .eq(ObjectUtil.isNotEmpty(params.getOrderStatus()), Storage::getOrderStatus, params.getOrderStatus())
                .eq(ObjectUtil.isNotEmpty(params.getCreateStatus()), Storage::getCreateStatus, params.getCreateStatus())
                .eq(ObjectUtil.isNotEmpty(params.getUpdateStatus()), Storage::getUpdateStatus, params.getUpdateStatus())
                .eq(ObjectUtil.isNotEmpty(params.getBusinessId()), Storage::getBusinessId, params.getBusinessId())
                .eq(ObjectUtil.isNotEmpty(params.getContractId()), Storage::getContractId, params.getContractId())
                .eq(ObjectUtil.isNotEmpty(params.getProviderId()), Storage::getProviderId, params.getProviderId());
        String flag = params.getFlag();
        // 0 补货 1 入库 3 出库
        if ("0".equalsIgnoreCase(flag)) {
            lqw.ne(Storage::getRepairStatus, "1");
        } else if ("1".equalsIgnoreCase(flag)) {
            lqw.eq(Storage::getRepairStatus, "1");
        } else {
            lqw.eq(Storage::getWareoutStatus, "0");
        }
        String search = params.getSearch();
        if (ObjectUtil.isNotEmpty(search)) {
            lqw.like(Storage::getOrderId, search).or()
                    .like(Storage::getCreateBy, search).or()
                    .like(Storage::getUpdateBy, search).or();
        }
        String dateTime = params.getDateTime();
        if (ObjectUtil.isNotEmpty(dateTime)) {
            lqw.like(Storage::getCreateTime, dateTime).or()
                    .like(Storage::getUpdateTime, dateTime);
        }
        page = storageService.page(page, lqw);
        List<Storage> records = page.getRecords();
        if (ObjectUtil.isEmpty(records)) {
            return AjaxResult.success();
        }
        return AjaxResult.success()
                .put("rows", records)
                .put("total", page.getTotal());
    }

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("{id}")
    public AjaxResult selectOne(@PathVariable Serializable id) {
        Storage byId = storageService.getById(id);
        ArrayList<Long> longs = new ArrayList<>();
        longs.add(Convert.toLong(byId.getProductId()));
        longs.add(Convert.toLong(byId.getBatchId()));
        byId.setProductName(longs);

        Ware byId1 = wareService.getById(byId.getWareId());

        Ware byId2 = wareService.getById(byId1.getParendId());
        // 一级
        ArrayList<Long> longs1 = new ArrayList<>();
        longs1.add(Convert.toLong(byId2.getParendId()));
        // 二级
        longs1.add(Convert.toLong(byId2.getId()));
        // 三级
        longs1.add(Convert.toLong(byId1.getId()));
        byId.setWareName(longs1);
        StorageDto storageDto = new StorageDto();
        BeanUtil.copyProperties(byId, storageDto);
        ArrayList<Goods> goods = storageService.getGoodListByStorageId(byId.getId());
        goods.stream().forEach(item -> {
            ArrayList<Integer> integers = new ArrayList<>();
            integers.add(Convert.toInt(item.getGoodsType()));
            integers.add(item.getId());
            item.setGoodsSelectName(integers);
        });
        storageDto.setGoodsList(goods);
        return AjaxResult.success(storageDto);
    }

    /**
     * 新增数据
     *
     * @param storage 实体对象
     * @return 新增结果
     */
    @PostMapping
    public AjaxResult insert(@RequestBody StorageDto storage) {
        String orderId = storage.getOrderId();
        if (ObjectUtil.isEmpty(orderId)) {
            orderId = OrderIdUtil.getOrderId();
        } else {
            orderId = OrderIdUtil.getOrderId(orderId);
        }
        storage.setOrderId(orderId);
        AjaxResult result = IsLegitiMate(storage);
        if (result != null) {
            return result;
        }

        // 生产单位
        List<Long> productName = storage.getProductName();
        storage.setProductId(Convert.toInt(productName.get(0)));
        // 批号
        storage.setBatchId(Convert.toInt(productName.get(1)));
        // 库位id
        List<Long> wareName = storage.getWareName();
        storage.setWareId(Convert.toInt(wareName.get(2)));
        if (ObjectUtil.isNotEmpty(storage.getId())) {
            return update(storage);
        }
        // 生产日期
        storage.setProduceTime(DateUtil.date());
        storageService.save(storage);
        // 新增商品信息
        List<Goods> goodsList = storage.getGoodsList();
        if (!goodsList.isEmpty()) {
            goodsList.stream().forEach(item -> {
                StorageGoods storageGoods = new StorageGoods(Convert.toInt(storage.getId()), Convert.toInt(item.getId()), item.getReplenishmentNum());
                storageGoodsService.save(storageGoods);
            });
        }
        return AjaxResult.success();
    }

    /**
     * 参数校验
     *
     * @param storage
     * @return
     */
    private static AjaxResult IsLegitiMate(StorageDto storage) {
        if (ObjectUtil.isEmpty(storage.getBusinessId())) {
            return AjaxResult.error("业务类型为空");
        }
        if (ObjectUtil.isEmpty(storage.getContractId())) {
            return AjaxResult.error("合同类型为空");
        }

        if (ObjectUtil.isEmpty(storage.getProviderId())) {
            return AjaxResult.error("供应商为空");
        }
        if (ObjectUtil.isEmpty(storage.getProductName())) {
            return AjaxResult.error("品牌为空");
        }
        if (ObjectUtil.isEmpty(storage.getWareName())) {
            return AjaxResult.error("仓库为空");
        }
        return null;
    }

    /**
     * 修改数据
     *
     * @param storage 实体对象
     * @return 修改结果
     */
    @PutMapping
    public AjaxResult update(@RequestBody StorageDto storage) {
        List<Goods> goodsList = storage.getGoodsList();
        if (ObjectUtil.isNotEmpty(goodsList)) {
            // 备注
            goodsList.stream().filter(item -> {
                if (ObjectUtil.isEmpty(item.getId())) {
                    return false;
                }
                return true;
            }).distinct().forEach(item -> {
                // 删除 在添加
                LambdaUpdateWrapper<StorageGoods> lqw1 = new LambdaUpdateWrapper<StorageGoods>()
                        .eq(StorageGoods::getStorageId, storage.getId());
                storageGoodsService.remove(lqw1);
                // 添加
                StorageGoods storageGoods = new StorageGoods(Convert.toInt(storage.getId()), item.getId(), item.getReplenishmentNum());
                storageGoodsService.save(storageGoods);
                LambdaUpdateWrapper<Goods> lqw = new LambdaUpdateWrapper<Goods>()
                        .eq(Goods::getId, item.getId())
                        .set(Goods::getRemark, item.getRemark());
                // 修改
                goodsService.update(lqw);
            });

        }
        return AjaxResult.success(storageService.updateById(storage));
    }

    /**
     * 删除数据
     *
     * @param id 主键结合
     * @return 删除结果
     */
    @DeleteMapping("{id}")
    public AjaxResult delete(@PathVariable Long id) {
        String s = Convert.toStr(id);
        List<String> split = StrUtil.split(s, ",");
        LambdaUpdateWrapper<Storage> lqw = new LambdaUpdateWrapper<Storage>()
                .in(Storage::getId, split);
        return AjaxResult.success(storageService.remove(lqw));
    }
}

